﻿
using EmperialApps.WeatherSpark.Data;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace EmperialApps.WeatherSpark.Agent {

    /// <summary>Renders the graph for the back of the Windows Phone wide live tile.</summary>
    public partial class TileWideFlipImage : TileImageBase {

        /// <summary>Initializes a new instance of the <see cref="TileWideFlipImage"/> class.</summary>
        public TileWideFlipImage( ) {
            InitializeComponent( );

            this.TileTitle.ClearValue( TextBlock.TextProperty );
            this.TileTitle.SetBinding( TextBlock.TextProperty, new Binding( "Title" ) { Source = this } );
        }


        /// <inheritdoc/>
        public override void DisplayValues( Forecast forecast, Units units, ForecastDisplayMode mode ) {
            // Get time values.
            DateTimeOffset now = DateTimeOffset.UtcNow.ToOffset( forecast.Start.Offset );
            DateTimeOffset date = now.GetDateOffset( );
            DateTimeOffset begin = date.AddDays( -1 );
            double hourOffset = 1 + (int)now.HoursFrom( forecast.Start );

            // Get temperature and setup time scale.
            forecast.GetTemperatureValues( units, ref this._temperature );
            double currentTemperature = this._temperature.GetInterpolatedValue( hourOffset, ConvertValue.Identity );
            const int Hours = 3 * ConvertValue.HoursPerDay;
            var timeScale = new Scale( false, this.Width, new double[] { 0, Hours } );

            // Display values.
            double beginOffset = begin.HoursFrom( forecast.Start );
            Scale valueTemplateScale = new Scale( true, this.TemperatureHeight, new double[] { Math.Round( currentTemperature ) } );
            Scale temperatureScale = DisplayTrace( this.TemperatureTrace, this.CurrentTimeMarker, this._temperature, valueTemplateScale, timeScale, beginOffset, hourOffset, hours: Hours );

            string temperatureUnit = units.GetTemperatureSymbol( );
            this.CurrentTemperatureLabel.Text = string.Format( "{0:0}\u200a\u2060\u00b0{1}", currentTemperature, temperatureUnit );
            DisplayTemperatureLabels( this.LowTemperatureTodayLabel, this.HighTemperatureTodayLabel, this._temperature, forecast.Start, units, date );
            DisplayTemperatureLabels( this.LowTemperatureTomorrowLabel, this.HighTemperatureTomorrowLabel, this._temperature, forecast.Start, units, date.AddDays( 1 ) );
            DisplayTemperatureLabels( this.LowTemperatureYesterdayLabel, this.HighTemperatureYesterdayLabel, this._temperature, forecast.Start, units, date.AddDays( -1 ) );

            this.DisplayNightBackground( forecast, timeScale, temperatureScale, begin );
            DisplayExtremeLine( this.ExtremeLine, this.Width, temperatureScale, units );
        }


        /// <inheritdoc/>
        protected override UIElementCollection ForecastPanelChildren {
            get { return this.ForecastPanel.Children; }
        }


        #region Private Members

        private DataValues _temperature;


        private double TemperatureHeight { get { return this.GraphRow.Height.Value; } }


        private static void DisplayTemperatureLabels( TextBlock lowLabel, TextBlock highLabel, DataValues temperature, DateTimeOffset start, Units units, DateTimeOffset date ) {
            double low, high;
            var extremes = temperature.TryGetExtremeValues( start, date, minimumCount: 0 );
            if( extremes.TryGetValues( out low, out high ) ) {
                lowLabel.Text = string.Format( "{0:0}\u00b0", low );
                highLabel.Text = string.Format( "{0:0}\u00b0", high );
            }
            else {
                lowLabel.Text = "";
                highLabel.Text = "";
            }
        }

        private void DisplayNightBackground( Forecast forecast, Scale timeScale, Scale temperatureScale, DateTimeOffset begin ) {
            var clip = (PathGeometry)this.NightBackground.Clip;
            Display.ClipNightBackground( clip, forecast.Location, forecast.Start, this._temperature, timeScale, temperatureScale, true, begin );
        }

        #endregion

    }

}
